/*=========================================================================
 Copyright (c) 2008, Nokia Corporation and/or its subsidiary(-ies).
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
     * Neither the name of the Nokia Corporation and/or its subsidiary(-ies)nor the
       names of its contributors may be used to endorse or promote products
       derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================================*/

#ifndef FIXED_H
#define FIXED_H


#include <e32base.h>

#define BITS 20
#define MUL2T 1048576

#define PI 3.14159265
#define FP2(s) (s<<BITS)
#define FP2_REAL(s) (s*MUL2T)
#define FP2_TO_REAL(s) (s/MUL2T)
#define DEC2(s) (s>>BITS)
#define MUL2(x,y) (((y) * (x)) >> BITS )
#define DIV2(x,y) ((y << BITS) / (x))

#define FP2_MAX (TInt)2047

// Reserved for future use.
enum TNumberFormat
	{
	// normal
	ENormal = 0,
	// 8 bits
	EFixed8 = 8,
	// 5 bits
	EFixed5 = 5,
	// 16 bits
	EFixed16 = 16
	};

/**
 * \class CFixed
 * \brief Fixed point class. The class implements basic arithmetics for fixed point
 * numbers. CFixed can be used instead of TReal when performance more critical than accuracy.
 * \note Symbian TClass.
 */
class CFixed
	{
public:
	/**
	 * \brief Empty constructor
	 */
	IMPORT_C CFixed();
	
	/**
	 * \brief Initializes CFixed with TReal value
	 */
	IMPORT_C CFixed( TReal aVal );

	/**
	 * \brief Initializes CFixed with TInt value
	 */	
	IMPORT_C CFixed( TInt aVal );
	
	/**
	 * \brief Initializes CFixed with TInt64 value
	 */	
	IMPORT_C CFixed( TInt64 aVal );

	/**
	 * \brief Set TInt value for the CFixed
	 */	
	IMPORT_C void operator=(TInt aVal);
	
	/**
	 * \brief Set TInt64 value for the CFixed
	 */		
	IMPORT_C void operator=(TInt64 aVal);
	
	/**
	 * \brief Set TReal value for the CFixed
	 */		
	IMPORT_C void operator=(TReal aVal);
	
	/**
	 * \brief Set CFixed value for the CFixed
	 */		
	IMPORT_C void operator=(CFixed aVal);

	/**
	 * \brief Bit shift
	 */	
	IMPORT_C CFixed operator<<(TInt aVal);
	
	/**
	 * \brief Bit shift
	 */	
	IMPORT_C CFixed operator>>(TInt aVal);
	
	/**
	 * \brief Add two CFixed variables
	 */		
	IMPORT_C CFixed operator+(CFixed aVal);

	/**
	 * \brief Subtract CFixed
	 */			
	IMPORT_C CFixed operator-(CFixed aVal);
	
	/**
	 * \brief Invert
	 */		
	IMPORT_C CFixed operator-();
	
	/**
	 * \brief Division
	 */		
	IMPORT_C CFixed operator/(CFixed aVal);

	/**
	 * \brief Multiply
	 */	
	IMPORT_C CFixed operator*(CFixed aVal);

	/**
	 * \brief += operator
	 */	
	IMPORT_C CFixed operator+=(TInt aVal);

	/**
	 * \brief -= operator
	 */	
	IMPORT_C CFixed operator-=(TInt aVal);

	/**
	 * \brief += operator
	 */	
	IMPORT_C CFixed operator+=(TReal aVal);

	/**
	 * \brief -= operator
	 */	
	IMPORT_C CFixed operator-=(TReal aVal);

	/**
	 * \brief += operator
	 */	
	IMPORT_C CFixed operator+=(TInt64 aVal);

	/**
	 * \brief -= operator
	 */	
	IMPORT_C CFixed operator-=(TInt64 aVal);

	/**
	 * \brief += operator
	 */	
	IMPORT_C CFixed operator+=(CFixed aVal);

	/**
	 * \brief -= operator
	 */	
	IMPORT_C CFixed operator-=(CFixed aVal);

	/**
	 * \brief ++ operator
	 */	
	IMPORT_C CFixed operator++();

	/**
	 * \brief -- operator
	 */	
	IMPORT_C CFixed operator--();

	/**
	 * \brief Compare two CFixed numbers using smaller than operator
	 */	
	IMPORT_C TBool operator<(CFixed aVal);

	/**
	 * \brief Compare two CFixed numbers using greater than operator
	 */	
	IMPORT_C TBool operator>(CFixed aVal);

	/**
	 * \brief Compare two CFixed numbers using equals operator
	 */	
	IMPORT_C TBool operator==(CFixed aVal);

	/**
	 * \brief Compare two CFixed numbers using not equal operator
	 */	
	IMPORT_C TBool operator!=(CFixed aVal);

	/**
	 * \brief Compare two CFixed numbers using smaller than or equal operator
	 */	
	IMPORT_C TBool operator<=(CFixed aVal);

	/**
	 * \brief Compare two CFixed numbers using greater than or equal operator
	 */	
	IMPORT_C TBool operator>=(CFixed aVal);

	/**
	 * \brief Return the raw internal value of the CFixed implementation.
	 */	
	IMPORT_C TInt64 Val();

	/**
	 * \brief Round CFixed to TInt64 using floor
	 */	
	IMPORT_C TInt64 Int();

	/**
	 * \brief Convert CFixed to TReal
	 */	
	IMPORT_C TReal Real();

	TInt64 iValue;

private:
	IMPORT_C CFixed( TBool aFixed, TInt64 aNum );
	IMPORT_C CFixed( TInt64 aVal, TNumberFormat aFormat );

private:
	TNumberFormat iFormat;
	};


#endif
